using System;
using System.Globalization;
using System.Xml;

namespace FreeFlow.Client
{
	/// <summary>
	/// A status field.
	/// </summary>
  [Serializable]
	public class StatusField : Field
	{
    internal StatusField(Form form, XmlElement fieldNode)
      : base(form, fieldNode)
    {
      if (fieldNode != null)
      {
        safeImageName = fieldNode.GetAttribute("SafeImage");
        cautionImageName = fieldNode.GetAttribute("CautionImage");
        dangerImageName = fieldNode.GetAttribute("DangerImage");
        percentage = fieldNode.GetAttribute("Percentage") == "1";
      }
    }

    internal override void FillValue(XmlElement node)
    {
      base.FillValue(node);
      XmlElement statusElement = node["StatusField"];
      if (statusElement != null)
      {
        process = statusElement.GetAttribute("StatusMap");
        action = statusElement.GetAttribute("StatusAction");
        
        // URL
        url = null;
        string urlString = statusElement.GetAttribute("StatusURL");
        if ((urlString != null) && (urlString.Length > 0))
          url = new Uri(urlString);
        
        double.TryParse(statusElement.GetAttribute("SafeThreshold"), NumberStyles.Any,
          CultureInfo.InvariantCulture, out safeThreshold);
        double.TryParse(statusElement.GetAttribute("DangerThreshold"), NumberStyles.Any,
          CultureInfo.InvariantCulture, out dangerThreshold);
        double.TryParse(statusElement.GetAttribute("HundredPercent"), NumberStyles.Any,
          CultureInfo.InvariantCulture, out hundredPercent);
      }
    }

    #region properties
    private string process;
    /// <summary>
    /// Gets the process that should be started when the user clicks the field.
    /// </summary>
    public string Process
    {
      get
      {
        return process;
      }
    }

    private string action;
    /// <summary>
    /// Gets the process action that should be started when the user clicks the field.
    /// </summary>
    public string Action
    {
      get
      {
        return action;
      }
    }

    private Uri url;
    /// <summary>
    /// Gets the URL that should be opened when the user clicks the field.
    /// </summary>
    public Uri Url
    {
      get
      {
        return url;
      }
    }

    private bool percentage;
    /// <summary>
    /// Gets a value indicating whether the safety and danger thresholds for this <see cref="StatusField"/> are a percentage.
    /// </summary>
    /// <value>
    /// 	<c>true</c> if the thresholds are percentages; otherwise, <c>false</c>.
    /// </value>
    public bool Percentage
    {
      get
      {
        return percentage;
      }
    }

    private double hundredPercent;
    /// <summary>
    /// Gets the value representing 100 percent.
    /// </summary>
    public double HundredPercent
    {
      get
      {
        return hundredPercent;
      }
    }

    private double safeThreshold;
    /// <summary>
    /// Gets the safe threshold for the field.
    /// </summary>
    public double SafeThreshold
    {
      get
      {
        return safeThreshold;
      }
    }

    private double dangerThreshold;
    /// <summary>
    /// Gets the danger threshold for the field.
    /// </summary>
    public double DangerThreshold
    {
      get
      {
        return dangerThreshold;
      }
    }

    private string safeImageName;
    private byte[] safeImage;
    private string cautionImageName;
    private byte[] cautionImage;
    private string dangerImageName;
    private byte[] dangerImage;

    private void CheckImage(ref byte[] image, string fileName)
    {
      if (image == null)
      {
        // get from server
        if (Connection != null)
          image = Connection.GetAttachment(AttachmentType.Procedure, fileName, Form.Procedure);
      }
    }

    /// <summary>
    /// Gets the image that should be currently displayed, based on the current safety threshold and 
    /// danger threshold and value of the field.
    /// </summary>
    public byte[] Image
    {
      get
      {
        double fieldValue;
        double.TryParse(Value, NumberStyles.Any, CultureInfo.InvariantCulture, out fieldValue);

        if (hundredPercent > 0)
          fieldValue = (fieldValue * 100) / hundredPercent;

        if (safeThreshold < dangerThreshold)
        {
          if (fieldValue <= safeThreshold)
          {
            CheckImage(ref safeImage, safeImageName);
            return safeImage;
          }
          else if ((fieldValue > safeThreshold) && (fieldValue < dangerThreshold))
          {
            CheckImage(ref cautionImage, cautionImageName);
            return cautionImage;
          }
          else
          {
            CheckImage(ref dangerImage, dangerImageName);
            return dangerImage;
          }
        }
        else
        {
          if (fieldValue >= safeThreshold)
          {
            CheckImage(ref safeImage, safeImageName);
            return safeImage;
          }
          else if ((fieldValue < safeThreshold) && (fieldValue > dangerThreshold))
          {
            CheckImage(ref cautionImage, cautionImageName);
            return cautionImage;
          }
          else
          {
            CheckImage(ref dangerImage, dangerImageName);
            return dangerImage;
          }
        }
      }
    }

    #endregion
	}
}
